/**
 *  Copyright 2011 Marco Berri - marcoberri@gmail.com
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and limitations under the License.
 **/
package com.cron;

import java.io.IOException;
import java.text.ParseException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import org.quartz.impl.StdSchedulerFactory;
import org.quartz.*;

import java.util.*;
import com.utils.Default;
import com.utils.StringUtil;

/**
 *
 * @author Marco Berri marcoberri@gmail.com
 */
public class OsQuartz extends com.Base {

    /**
     *
     */
    public static final String QUARTZ_FACTORY_KEY = "org.quartz.impl.StdSchedulerFactory.KEY";
    private boolean performShutdown = true;
    private Scheduler scheduler = null;

    /**
     *
     * @param cfg
     * @throws javax.servlet.ServletException
     */
    @Override
    public void init(ServletConfig cfg) throws javax.servlet.ServletException {
        try {
            super.init(cfg);
            StdSchedulerFactory factory;
            //try {
            debug("quartz - start");

            String shutdownPref = cfg.getInitParameter("shutdown-on-unload");

            if (shutdownPref != null) {
                performShutdown = Boolean.valueOf(shutdownPref).booleanValue();
            }

            Properties prop = new Properties();
            prop.setProperty("org.quartz.scheduler.instanceName", "OsQuarz_mbfasturl");
            prop.setProperty("org.quartz.scheduler.instanceId", "" + System.nanoTime());
            //conf per storare in ram
            prop.setProperty("org.quartz.jobStore.class", "org.quartz.simpl.RAMJobStore");
            prop.setProperty("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
            prop.setProperty("org.quartz.threadPool.threadCount", "1");
            factory = new StdSchedulerFactory(prop);
            debug("quartz - proterties " + prop);
            scheduler = factory.getScheduler();
            debug("quartz - cron map " + this.conf.getCron());
            if (!this.conf.getCron().isEmpty()) {
                int i = 0;
                for (Map<String, Object> e : this.conf.getCron()) {

                    if(StringUtil.isNullOrEmpty(Default.toString(e.get("clazz"))))
                        continue;
                        
                    JobDetail job = null;
                    try {
                        job = new JobDetail("job" + i, "group" + i, com.utils.ClassUtil.newInstance(Default.toString(e.get("clazz"))).getClass());
                    } catch (Exception e2) {
                        fatal("", e2);
                        continue;
                    }

                    job.getJobDataMap().put("conf", this.conf);
                    job.getJobDataMap().put(com.conf.Log.TAG_XML_LOG, this.cron_log);
                    job.getJobDataMap().put("conn_url", this.conn_url);
                    job.getJobDataMap().put("conn_stats", this.conn_stats);
                    job.getJobDataMap().put("path_app_root", this.path_app_root);
                    if( e.get(com.conf.Main.TAG_XML_CRON_JOB_PROPERTIES) != null)
                        job.getJobDataMap().put(com.conf.Main.TAG_XML_CRON_JOB_PROPERTIES, e.get(com.conf.Main.TAG_XML_CRON_JOB_PROPERTIES));
                    Trigger trigger = null;
                    try {
                        trigger = new CronTrigger("trigger" + i, "group" + i, "job" + i, "group" + i, Default.toString(e.get("time")));
                    } catch (ParseException ex) {
                        fatal("ParseException", ex);
                    }
                    // Schedule the job with the trigger
                    scheduler.scheduleJob(job, trigger);
                    i++;
                }
            }
            scheduler.start();
            String factoryKey = QUARTZ_FACTORY_KEY;
            application.setAttribute(factoryKey, factory);
            debug("quartz - end with factoryKey: " + factoryKey);

        } catch (SchedulerException ex) {
            fatal("SchedulerException", ex);
        }

    }

    /**
     *
     */
    @Override
    public void destroy() {

        if (!performShutdown) {
            return;
        }

        if (scheduler != null) {
            try {
                scheduler.shutdown();
            } catch (SchedulerException ex) {
                fatal("SchedulerException", ex);
            }
        }
    }

    /**
     *
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.sendError(HttpServletResponse.SC_FORBIDDEN);
    }

    /**
     *
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.sendError(HttpServletResponse.SC_FORBIDDEN);
    }
}
